<?php

namespace G4T\Form;

use \G4T\Util\MetadataItem;
use \G4T\Util\ClassMetadata;

class FormBuilder
{
    private $fields;

    /**
     * @var \Zend_Form
     */
    private $form;

    public function __construct($entity, array $params = array(), $formClass = "default")
    {
        $this->fields = ClassMetadata::getMetadata($entity);

        $formClass = FormFabric::getFormClass($formClass);
        $formClass->setOptions($params);
        $this->form = $formClass;
        $this->applyParams($params);
    }

    private function applyParams(array $params)
    {
        if (isset($params['method'])) {
            $this->form->setMethod($params['method']);
        } else {
            $this->form->setMethod('post');
        }

        if (isset($params['action'])) {
            $this->form->setAction($params['action']);
        }

        if (isset($params['class'])) {
            $this->form->setAttrib('class', $params['class']);
        }

        if (isset($params['id'])) {
            $this->form->setAttrib('id', $params['id']);
        }
    }


    public function addField($param, $type = false, array $params = array())
    {
        if ($type) {
            $element = $this->createFormElement($param, $type);
        } else {
            $element = $this->decideElementType($param);
        }
        $element->setOptions($params);
        $field = isset($this->fields[$param]) ? $this->fields[$param] : false;

        if ($field) {
            $element->setRequired($field->isRequired());
            if (!$element instanceof \G4T\Form\Element\ElementInterface) {
                $class = get_class($element);
                throw new \Exception("Form  $class should be instance of \\G4T\\Form\\Element\\ElementInterface");
            }
            $element->setParams($field->getParam());
        }
        $this->form->addElement($element);
        return $this;
    }

    /**
     * @param $param
     * @param $type
     * @return \Zend_Form_Element
     */
    private function createFormElement($param, $type)
    {
        $class = '\G4T\Form\Element\\' . ucfirst($type) . 'Element';
        $title = isset($this->fields[$param]) ? $this->fields[$param]->getTitle() : null;
        $element = new $class($param);
        if (!($element instanceof \Zend_Form_Element_Hidden)) {
            $element->setLabel(ucfirst($title) . ':');
        }
        return $element;
    }

    private function decideElementType($param)
    {
        $field = $this->fields[$param];
        return $this->createFormElement($param, $field->getType());
    }

    /**
     * @return \Zend_Form
     */
    public function getForm()
    {
        return $this->form;
    }

    /**
     * @static
     * @param $entity
     * @param array $params
     * @return \G4T\Form\FormBuilder
     */
    public static function createFormBuilder($entity, array $params = array(), $type = 'default')
    {
        return new self($entity, $params, $type);
    }
}
